package com.smartEdu.utils;

import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

//import org.dom4j.Document;
//import org.dom4j.Element;
//import org.dom4j.SAXBuilder;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.springframework.beans.BeanUtils;
import org.xml.sax.InputSource;

public class BeanUtil {

	/**
	 * 通过xml字符串转换成给定类的对象
	 * 
	 * @param xml
	 *            需要转成对象的字符串
	 * @param c
	 *            返回对象的类[Class]
	 * @return 返回对象的实例 <br>
	 *         1.转换过程中不会操作任何xml的属性操作，值是一个标签对应一个属性来操作的 <br>
	 *         2.参数Class<?> c对应的类，需要设置的属性都必须有getter，setter方法
	 */
	public static <T> T xmlToJavaBean(String xml, Class<T> c) {
		T t = null;
		try {
			t = c.newInstance();
			SAXBuilder sb = new SAXBuilder();
			StringReader read = new StringReader(xml);
			InputSource source = new InputSource(read);
			Document doc = sb.build(source);
			Element root = doc.getRootElement();
			conver(root, c, t);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return t;
	}

	@SuppressWarnings("unchecked")
	private static void conver(Element e, Class<?> clazz, Object o) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		List<Element> el = e.getChild("Message").getChildren();
		for (Element element : el) {

			String eName = element.getName();
			String methodName = "set" + eName.substring(0, 1).toUpperCase() + eName.substring(1);
			Method[] ms = clazz.getMethods();
			for (Method m : ms) {
				if (m.getName().equals(methodName)) {
					Class<?>[] c = m.getParameterTypes();
					String text = element.getTextTrim();
					Object v = null;
					String cn = c[0].getSimpleName();

					if ("int".equals(cn)) {
						v = Integer.parseInt(text);
					} else if ("long".equals(cn)) {
						v = Long.parseLong(text);
					} else if ("double".equals(cn)) {
						v = Double.parseDouble(text);
					} else if ("float".equals(cn)) {
						v = Float.parseFloat(text);
					} else {
						v = text;
					}
					m.invoke(o, v);
				}
			}
		}
	}

	private static void convery(Element e, Class<?> clazz, Object o) throws SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {

		String en = e.getName();
		if ("ROOT".equals(en)) {
			List<Element> el = e.getChildren();
			for (Element e1 : el) {
				convery(e1, clazz, o);
			}
		} else {
			List<Element> el = e.getChildren();
			if (el.size() > 0) {

				String childClassName = e.getName();

				String methodName = "get" + childClassName.substring(0, 1).toUpperCase() + childClassName.substring(1);

				Class<?> clazz1 = null;
				Method[] ms = clazz.getMethods();
				for (Method m : ms) {
					if (methodName.equals(m.getName())) {
						clazz1 = m.getReturnType();
					}
				}
				// try {
				// clazz1 = Class.forName(ncn);
				// } catch (Exception e2) {
				// System.err.println(ncn + " 实例化失败，请检查是否存在这个类 ");
				// }
				if (null == clazz1) {
					// 没有找到对应的类，这里只是忽略
					System.out.println(methodName + " 方法未找到，或者返回类型不正确 ");
					return;
				}
				Object o1 = clazz1.newInstance();

				try {
					// 反射获取set方法,帮o1的值设置进o里面
					Method m = clazz.getMethod(methodName, clazz1);
					m.invoke(o, o1);
				} catch (Exception e2) {
					// 应该是没有找到对应的方法，忽略
					System.err.println(methodName + " 方法调用失败，请检查方法是否存在");
					return;
				}

				for (Element e1 : el) {
					convery(e1, clazz1, o1);
				}
			} else {
				String eName = e.getName();
				String methodName = "set" + eName.substring(0, 1).toUpperCase() + eName.substring(1);
				Method[] ms = clazz.getMethods();
				for (Method m : ms) {
					if (m.getName().equals(methodName)) {
						Class<?>[] c = m.getParameterTypes();
						// 目前只支持带一个参数的情况
						String text = e.getTextTrim();
						Object v = null;
						String cn = c[0].getSimpleName();

						if ("int".equals(cn)) {
							v = Integer.parseInt(text);
						} else if ("long".equals(cn)) {
							v = Long.parseLong(text);
						} else if ("double".equals(cn)) {
							v = Double.parseDouble(text);
						} else if ("float".equals(cn)) {
							v = Float.parseFloat(text);
						} else {
							v = text;
						}
						m.invoke(o, v);
					}
				}
			}
		}
	}
	
	/**
	 * 对象复制
	 * @param src 源对象
	 * @param cls 目标类型
	 * @return 目标对象
	 * @throws Exception
	 */
	public static <T> T copyProperties(Object src,Class<T> cls) throws Exception{
		T target = cls.newInstance();
		BeanUtils.copyProperties(src,target);
		return target;
	}
	
	/**
	 * list集合复制
	 * @param srcs 源集合
	 * @param cls 目标集合类型
	 * @return
	 * @throws Exception
	 */
	public static <T> List<T> copyList(List<?> srcs,Class<T> cls) throws Exception{
		List<T> target = null;
		if(srcs != null){
			for(Object o:srcs){
				if(target == null){
					target = new ArrayList<T>();
				}
				target.add(copyProperties(o,cls));
			}
		}
		return target;
	}

}
